package com.crawData;

import com.crawData.model.DouyinMode;
import com.crawData.service.CrawDataService;
import com.alibaba.excel.EasyExcel;

import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;


import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.*;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;


import javax.net.ssl.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class ApplicationTests {

	@Autowired
	@Qualifier("crawDataDouYinServiceImpl")
   private CrawDataService crawDataService;

	/**
	 * 测试爬取抖音视源视频测试-控制谷歌浏览器(通过自动化工具)
	 */
	@Test
	public void contextLoads() {
      log.info("start");
		//String url="https://www.douyin.com/user/MS4wLjABAAAAJQga4DDzyFwr0xucCQSsg34xvrKwIyKtk1o_HSeLWphxIfjFLoahw44sjZClRoKT?from_tab_name=main";
		String url="https://www.douyin.com/user/MS4wLjABAAAA8035N_Be0iOxBvGr0vQZD2g3p5zAarwWET3wLOJkTBc?from_tab_name=main&vid=7429614687639047474";
		HashMap parms = new HashMap();
		parms.put("url",url);
		Object crawl = crawDataService.crawl(parms);
		List<DouyinMode> douyinModes = JSONObject.parseArray(JSONObject.toJSONString(crawl), DouyinMode.class);
		log.info("result{}",JSONObject.toJSONString(douyinModes));
		log.info("end ");
	}


	@Test
	public void test01() throws IOException {
		//下载视频需要在多拼接一层url
		String videoUrl = "https://v26-web-prime.douyinvod.com/video/tos/cn/tos-cn-ve-15/osBJI3iv77NGrFRmAQBAEmc6ebzgYBjABqiZfK/?a=6383&ch=0&cr=0&dr=0&er=0&cd=0%7C0%7C0%7C0&cv=1&br=1333&bt=1333&cs=0&ds=4&ft=AQHeBxbkRR0sWrC12D12Nc0iPMgzbL5Sez1U_4l7nr2JNv7TGW&mime_type=video_mp4&qs=0&rc=OWVmNDY7Ojs7NmZoMzc1PEBpajg3eHQ5cjZvdTMzNGkzM0BjLTM2Xi8wNmMxYWIuLTExYSNvZm9hMmRjM2ZgLS1kLWFzcw%3D%3D&btag=80000e00008000&cquery=100b&dy_q=1729860949&expire=1729864560&feature_id=46a7bb47b4fd1280f3d3825bf2b29388&l=20241025205549E901E1986435F4942C88&ply_type=4&policy=4&signature=317e316e91d80b929e4f9449d13b8234&tk=webid&webid=63bdc4b4b456901f349a081bfd3a24da10a1c6623f0a2d5eadd83f51c9f4d112f99e23943e4db7cea450accb7224c3cb7b7ffd89d611f3427bad3aac9c91fd0acf504ef336aa826d49d226ddae83e053cf01efe5d49dc6716339e4cd114c6449524056d2b0dbfb74f62f08997b40ce796b2a6a072a79f24a65d077b98e92657ee4f538748e9b3e794475ad220ec7211a82cc07734256aaa92403f40472642277-3d13d2630d1cb996b19b398f96dc6b51"; // 替换为实际的 HTTPS 视频 URL
		String destinationFile = "G:\\douyin\\data\\ceshi.mp4"; // 替换为你希望保存的文件名

		try {
			// 创建一个忽略 SSL 证书验证的 TrustManager
			TrustManager[] trustAllCerts = new TrustManager[]{
					new X509TrustManager() {
						@Override
						public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
						}

						@Override
						public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
						}

						@Override
						public X509Certificate[] getAcceptedIssuers() {
							return new X509Certificate[0];
						}
					}
			};

			// 安装这个 TrustManager 到 SSLContext
			SSLContext sslContext = SSLContext.getInstance("SSL");
			sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

			// 创建一个 HttpsURLConnection 并设置 SSLContext
			HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
			HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
				@Override
				public boolean verify(String hostname, SSLSession session) {
					return true; // 忽略主机名验证
				}
			});
			downloadFile(videoUrl, destinationFile);
			System.out.println("视频下载成功！");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static final int BUFFER_SIZE = 4096;



	public static void downloadFile(String fileURL, String saveFilePath) throws Exception {
		URL url = new URL(fileURL);
		HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();

		// 对于 HTTPS，通常不需要额外设置，因为 Java 的 HttpURLConnection 会自动处理 SSL
		// 但如果你有特殊需求，比如使用自定义的信任管理器或密钥库，你需要在这里配置

		// 允许从 HTTPS URL 读取数据（这是默认行为，但明确写出来有助于理解）
		httpConn.setRequestMethod("GET");
		httpConn.setDoOutput(false); // 对于下载文件，这个通常不需要设置为 true，但设置为 false 也不会影响

		int responseCode = httpConn.getResponseCode();

		// 检查响应码是否为 HTTP OK
		if (responseCode == HttpURLConnection.HTTP_OK) {
			try (OutputStream outputStream = new FileOutputStream(saveFilePath);
				 InputStream inputStream = httpConn.getInputStream()) {

				byte[] buffer = new byte[BUFFER_SIZE];
				int bytesRead = -1;

				// 从输入流读取数据并写入到输出流中
				while ((bytesRead = inputStream.read(buffer)) != -1) {
					outputStream.write(buffer, 0, bytesRead);
				}

				outputStream.flush();
			}
		} else {
			throw new RuntimeException("无法下载文件，HTTP 错误码：" + responseCode);
		}

		// 断开连接（虽然 Java 7 及以上版本的 HttpURLConnection 会在 finally 块中自动关闭连接，但明确断开是一个好习惯）
		httpConn.disconnect();
	}


//	class DouyinMode{
//		@ExcelProperty("视频描述")
//	   String desc;
//		@ExcelProperty("图片地址")
//	   String img;
//		@ExcelProperty("视频地址")
//	   String video;
//
//		public String getDesc() {
//			return desc;
//		}
//
//		public void setDesc(String desc) {
//			this.desc = desc;
//		}
//
//		public String getImg() {
//			return img;
//		}
//
//		public void setImg(String img) {
//			this.img = img;
//		}
//
//		public String getVideo() {
//			return video;
//		}
//
//		public void setVideo(String video) {
//			this.video = video;
//		}
	//}

	/**
	 * 爬取抖音视源视频测试-控制谷歌浏览器(通过自动化工具)
	 */
	@Test
	public void test02(){

		// 设置 Chrome 驱动路径
		String paht="D:\\dev\\chromedriver-win64_129.0.6668.101\\chromedriver-win64\\chromedriver.exe";
		System.setProperty("webdriver.chrome.driver", paht);

		// 初始化 Chrome 选项
		ChromeOptions options = new ChromeOptions();
		// 如果需要，可以设置代理、禁用GPU等

		// 使用 Chrome 选项初始化 WebDriver
		WebDriver driver = new ChromeDriver(options);
		try {
			String url="https://www.douyin.com/user/MS4wLjABAAAAJQga4DDzyFwr0xucCQSsg34xvrKwIyKtk1o_HSeLWphxIfjFLoahw44sjZClRoKT?from_tab_name=main";
			//String url="https://www.douyin.com/user/MS4wLjABAAAA-CI3a8kMhR4JIpBpRr9mBrx8Vm6yw00-cjBGYzBSdJ0?from_tab_name=main";
			driver.get(url);
			//  需要要睡眠6秒等待登录页面弹出
			Thread.sleep(60*100);
			//关闭登录窗口
			WebElement elementByClassName1 = ((ChromeDriver) driver).findElementByClassName("douyin-login__close");
 			elementByClassName1.click();
			 //获取全部作品
			WebElement allZuoPin = ((ChromeDriver) driver).findElementByClassName("pCVdP6Bb");
			List<WebElement> li = allZuoPin.findElements(By.tagName("li"));
			//收集 a标签跳转地址
			HashMap<String,Map> allAhref=new HashMap();
			for (WebElement webElement : li) {
				//获取 a标签视频链接进行跳转
				String videPath = webElement.findElement(By.tagName("a")).getAttribute("href");
				//获取 ima信息
				String imgPath = webElement.findElement(By.tagName("img")).getAttribute("src");
				//视频描述
				String altDesc = webElement.findElement(By.tagName("img")).getAttribute("alt");

				//保存视频，图片地址，视频描述
				HashMap<String,String> imageAndAltDesc=new HashMap();
				imageAndAltDesc.put("img",imgPath);
				imageAndAltDesc.put("video",videPath);
				allAhref.put(altDesc,imageAndAltDesc);
			}
			//获取视频的源地址

			HashMap<String,String> sourceListFail=new HashMap<>();
            // 使用 EasyExcel 导出数据到 Excel 文件
			List<DouyinMode> result=new ArrayList<>();
			for (Map.Entry<String, Map> stringObjectEntry : allAhref.entrySet()) {

				//获取视频描述
				String altDesc = stringObjectEntry.getKey();
				//获取视频地址
				Object href = stringObjectEntry.getValue().get("video");
				//img
				Object img = stringObjectEntry.getValue().get("img");
				try {
					driver.get(String.valueOf(href));
					//  需要要睡眠6秒等待登录页面弹出
					Thread.sleep(60*100);
					//关闭登录窗口
					WebElement elementByClassName2 = ((ChromeDriver) driver).findElementByClassName("douyin-login__close");
					elementByClassName2.click();
					System.out.println("跳转到"+href+"页面");

					// 获取视频源链接
					String sourcePath ="";
					List<WebElement> elements = driver.findElement(By.tagName("video")).findElements(By.tagName("source"));
					if (elements.size()>0){
						  sourcePath = driver.findElement(By.tagName("video")).findElements(By.tagName("source")).get(3).getAttribute("src");
					}else {
						  sourcePath = driver.findElement(By.tagName("video")).getAttribute("src");
					}


					DouyinMode douyinMode=new DouyinMode();
					// 设置超链接

					douyinMode.setDesc(altDesc);
					douyinMode.setImg(String.valueOf(img));
					douyinMode.setVideo(sourcePath);

					result.add(douyinMode);


				}catch (Exception e){
					System.out.println(e);
					sourceListFail.put(altDesc,String.valueOf(stringObjectEntry.getValue().get("video")));
				}
			}
			//导出源视频链接，视频名称为表格
			String fileName = "G:\\douyin\\抖音指定博主的原视频链接测试Demo.xlsx"; // 导出文件的名称




			EasyExcel.write(fileName)
					.head(DouyinMode.class)
					.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
							.
					sheet("导出成功视频链接")
					.doWrite(result);

		} catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
			driver.quit();
		}
	}

	@Test
	public void test03() throws InterruptedException {
		// 设置 Chrome 驱动路径
		String paht="D:\\dev\\chromedriver-win64_129.0.6668.101\\chromedriver-win64\\chromedriver.exe";
		System.setProperty("webdriver.chrome.driver", paht);

		// 初始化 Chrome 选项
		ChromeOptions options = new ChromeOptions();
		// 如果需要，可以设置代理、禁用GPU等
		// 使用 Chrome 选项初始化 WebDriver
		WebDriver driver = new ChromeDriver(options);
		driver.get("https://www.douyin.com/");
		//driver.get("https://www.douyin.com/aweme/v1/play/?aid=6383&app_name=aweme&channel=channel_pc_web&device_platform=web&did=0&file_id=cc0b6418dc5c432c8927bd62620245b9&fp=verify_m291hn5q_0bac8ed3_5672_c789_9c4f_57f1d2beaba8&is_play_url=1&line=0&referer=&sign=ff308787cb7e630b1e1612afd9648859&source=PackSourceEnum_AWEME_DETAIL&target=7400330829945195830&uifid=60b2ef133e5e740633c50bb923c1ddfcacd13dfeee1bbba287269d01840b457b6619d61c84f71c52810e89271f6bc4ff7b65af8b7a94065e5be42d57d3743b2e5723f201a898d6c480c9980671eac78691c6f5bba2d7714a30ca5e1a636acc1590fe153f1fcca0b33ff8ca2ae89915cecd22f0b9364a052434e4cad7e1db17699e0ee9900fb0a92114724e7ba4f7893d5f688c4548e5668a78561acc83b9c8d4&user_agent=Mozilla%2F5.0%20%28Windows%20NT%2010.0%3B%20Win64%3B%20x64%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F129.0.0.0%20Safari%2F537.36&video_id=v0200fg10000cqpk2svog65sasaq88o0&webid=7425619744881624617&downgrade_264=1&__vid=7400330829945195830");
		Thread.sleep(30*100);

		//视频拉到最低下

	}

	@Test
	public void test04(){


		//获取指定对象的类
		DouyinMode douyinMode=new DouyinMode();
		Class<? extends DouyinMode> douyinModeClass = douyinMode.getClass();

		//获取类的所有属性
		Field[] declaredFields = douyinModeClass.getDeclaredFields();
		for (Field declaredField : declaredFields) {
			System.out.println("属性变量:"+declaredField.getName());
		}
		//获取类指定的属性
        try {
            Field desc = douyinModeClass.getDeclaredField("desc");
			System.out.println("desc:"+desc.getName());
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }

		//获取所有方法
		Method[] declaredMethods = douyinModeClass.getDeclaredMethods();
		for (Method declaredMethod : declaredMethods) {
			System.out.println("方法名:"+declaredMethod.getName());


            try {
				if (declaredMethod.getName().equals("testMethodB")){
					Object invoke = declaredMethod.invoke(douyinMode);
					System.out.println("testMethodB执行结果"+String.valueOf(invoke));
				}

            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }


		}
        //获取指定私有方法
        try {
            Method testMethodA = douyinModeClass.getDeclaredMethod("testMethodA");
			System.out.println("testMethodA:"+testMethodA.getName());
             //设置可以访问 私有方法
			testMethodA.setAccessible(true);
			Object invoke = testMethodA.invoke(douyinMode);
			System.out.println("testMethodA执行结果"+String.valueOf(invoke));
		} catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        System.out.println("ddd");
    }

}
